class BadConversion : public std::runtime_error {
public:
 BadConversion(const std::string& s)
      : std::runtime_error(s) {}
};
template
inline std::string stringify(_type x)
{
  std::ostringstream o;
  if (!(o << std::fixed << x))
    throw BadConversion("stringify()");
  return o.str();
}
#define TIFFSetR(pixel, x) ((unsigned char *)pixel)[0] = x
#define TIFFSetG(pixel, x) ((unsigned char *)pixel)[1] = x
#define TIFFSetB(pixel, x) ((unsigned char *)pixel)[2] = x
#define TIFFSetA(pixel, x) ((unsigned char *)pixel)[3] = x
using namespace std;
void rotate_point(double x,
                  double y,
                  double o_x,
                  double o_y,
                  double radians,
                  double &r_x,
                  double &r_y) {
  //1. calculate theta
  //tan theta = opp (y) / adj (x)
  double dx = x - o_x;
  double dy = y - o_y;
  if(dx < 0) dx = 0-dx;
  if(dy < 0) dy = 0-dy;
  int q=1;
  if((x >  o_x) && (y >= o_y)) q = 1;
  if((x >= o_x) && (y <  o_y)) q = 2;
  if((x <  o_x) && (y <= o_y)) q = 3;
  if((x <= o_x) && (y >  o_y)) q = 4;
  double theta;
  if(q == 1) theta  = atan(dy/dx);
  if(q == 2) theta  = atan(dx/dy);
  if(q == 3) theta  = atan(dy/dx);
  if(q == 4) theta  = atan(dx/dy);
  double     h = sqrt(dx*dx + dy*dy);
  if((dy==0) || (dx==0)) theta = 0;
  theta -= radians;
  for(;theta < 0;) { theta = 0 - theta; theta = ((2*3.14)/4) - theta; q++; if(q==5) q=1;}
  for(;theta > ((2*3.14)/4);) {theta -= ((2*3.14)/4); q–; if(q==0) q=4; }
  if(q == 1) { r_y = (sin(theta) * h); r_x = (cos(theta) * h); }
  if(q == 2) { r_x = (sin(theta) * h); r_y = (cos(theta) * h); }
  if(q == 3) { r_y = (sin(theta) * h); r_x = (cos(theta) * h); }
  if(q == 4) { r_x = (sin(theta) * h); r_y = (cos(theta) * h); }
  if(q == 1) {r_x = o_x + r_x; r_y = o_y + r_y;}
  if(q == 2) {r_x = o_x + r_x; r_y = o_y – r_y;}
  if(q == 3) {r_x = o_x – r_x; r_y = o_y – r_y;}
  if(q == 4) {r_x = o_x – r_x; r_y = o_y + r_y;}
}
class Image {
public:
  Image() {
  }
  void load_tiff(string input_filename) {
    m_image_data.clear();
    TIFF* tif = TIFFOpen(input_filename.c_str(), “r”);
    if (tif) {
      uint32 w, h;
      size_t npixels;
      uint32* raster;
      TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
      TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
      npixels = w * h;
      m_width = w;
      m_height = h;
      raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
      if (raster != NULL) {
	if (TIFFReadRGBAImageOriented(tif, w, h, raster,ORIENTATION_TOPLEFT, 0)) {
	  for(size_t n=0;n(m_width*m_height,0);
  }
  Image rotate(size_t o_x,size_t o_y,double radians,uint32_t bg_val) {
    return rotate_source(o_x,o_y,radians,bg_val);
  }
  Image rotate_source(size_t o_x,size_t o_y,double radians,uint32_t bg_val) {
     Image new_image; // image to copy data in to
     size_t pad;
     if(m_width > m_height) pad = m_width;
                       else pad = m_height;
     new_image.m_width  = pad*4;
     new_image.m_height = pad*4;
     new_image.zero_image();
    for(uint32_t cx=0;cx adjs;
            adjs.push_back(get(x+1,y));
            adjs.push_back(get(x-1,y));
            adjs.push_back(get(x,y+1));
            adjs.push_back(get(x,y-1));
            int perform_set=0;
            for(size_t n=0;n m_height) pad = m_width;
                      else pad = m_height;
    new_image.m_width  = pad*4;
    new_image.m_height = pad*4;
    new_image.zero_image();
    for(int32_t cx=0-pad;cx m_image_data;
  size_t m_width;
  size_t m_height;
};
int main(int argc, char* argv[]) {
  Image i;
  i.load_tiff(string(argv[1]));
  int n=0;
  for(double r=0;r<(2*3.141);r+=0.1) {
    //Image i2 = i.rotate(i.m_width/2,i.m_height/2,1.78525,0);
    Image i2 = i.rotate(i.m_width/2,i.m_height/2,r,0);
    //Image i2 = i.rotate(0,0,r,0);
    for(int x=0;x<10;x++) {
      for(int y=0;y<10;y++) {
          i2.set(x,y,0xFFFFFFFF);
      }
    }
    i2.fill_gaps(0);
    i2.save_tiff_rgb(string("img") + stringify(n) + string(".tif"));
    n++;
  }
}
[/sourcecode]